import Obj from "./Obj";

/**
 * 集合层次结构中的根接口。一个集合代表一组对象，称为它的元素。一些集合允许重复元素，而另一些则不允许。有些是有序的，有些是无序的。
 *
 * 此包不提供该接口的任何直接实现，但提供了更具体的子接口（如{@link Queue}和{@link List}的实现。
 *
 * 此包中的所有Collection实现类都允许您使用现有元素或不使用任何元素创建实例。实际上，如果您提供元素，集合将复制它们并生成所需实现类型的等效集合。
 * 集合没有办法强制执行此约定（因为接口不能包含构造函数），但此包中的所有Collection实现都符合在构造函数中传入初始元素的约定。
 *
 * 某些方法被指定为可选的。如果集合实现没有实现特定的操作，或无法实现，它应该定义相应的方法来抛出{@link UnsupportedOperationException}。
 *
 * 所有集合实现都禁止null和undefined元素，但是此包中提供了{@link NullableObj}用于存储空元素。尝试查询不合格元素的存在可能会引发异常，或者可能
 * 只是返回 false。
 *
 * Collections接口中的许多方法都是根据{@link Obj#equalsTo}方法定义的，例如方法{@link Collection#contains}中进行比较时会使用。
 *
 * @param E 集合中需要存入的元素
 * @see Iterable
 * @see O
 * @version 1.0
 */
export default interface Collection<E> extends Iterable<E>, Obj {

  /**
   * 返回此集合中的元素数。
   *
   * @return {number} 返回此集合中的元素数
   * @version 1.0
   */
  size(): number;

  /**
   * 返回此集合的容量。
   *
   * @return {number} 返回此集合的容量
   * @version 1.0
   */
  capacity(): number;

  /**
   * 返回此集合是否为空。
   *
   * @return {boolean} 如果此集合不包含任何元素，则返回true，否则返回false
   * @version 1.0
   */
  isEmpty(): boolean;

  /**
   * 返回此集合是否已满。
   *
   * @return {boolean} 如果此集合存储的元素已到达容量，则返回true，否则返回false。若容量为-1，则永远不会满容量
   */
  isFull(): boolean;

  /**
   * 返回此集合是否包含指定的元素。
   *
   * @param e 需要查找的元素
   * @return {boolean} 如果此集合包含该元素，则返回true，否则返回false
   * @version 1.0
   */
  contains(e: E): boolean;

  /**
   * 返回由集合内所有元素组成的迭代器。
   *
   * @return {Iterator<E>} 一个由集合内所有元素组成的迭代器
   * @see Iterator
   * @version 1.0
   */
  iterator(): Iterator<E>;

  /**
   * 返回由集合内所有元素组成的数组。
   *
   * 该数组内的元素会是集合中元素的<strong>浅拷贝</strong>，因此后续对集合的操作不会影响到数组的浅层，反之亦然。
   *
   * @return {E[]} 一个由集合内所有元素组成的数组
   * @version 1.0
   */
  toArray(): E[];

  /**
   * 尝试将指定的元素加入到集合中。
   *
   * 若集合不允许重复元素加入集合，则返回false。否则其他错误必须以异常的形式抛出。
   *
   * 若集合因该元素的加入发生了变化，则返回true。
   *
   * @param e 需要加入到集合中的元素
   * @return {boolean} 若集合因该元素的加入发生了变化，则返回true，否则返回false
   * @throws {UnsupportedOperationException} 此方法不受支持
   * @throws {FullCapacityException} 集合已经满了
   * @version 1.0
   */
  add(e: E): boolean;

  /**
   * 移除此集合中所有与指定元素相同的元素。
   *
   * 此方法会调用{@link Obj#equals}方法进行相等判断。
   *
   * @param e 与需要从集合中被删除的元素相等的元素
   * @return {boolean} 如果有元素从集合中被删除，则返回true，否则返回false
   * @throws {UnsupportedOperationException} 此方法不受支持
   * @version 1.0
   */
  remove(e: E): boolean;

  /**
   * 移除此集合中第一个与指定元素相同的元素。
   *
   * 此方法会调用{@link Obj#equals}方法进行相等判断。
   *
   * @param e 与需要从集合中被删除的元素相等的元素
   * @return {boolean} 如果有元素从集合中被删除，则返回true，否则返回false
   * @throws {UnsupportedOperationException} 此方法不受支持
   * @version 1.0
   */
  removeFirst(e: E): boolean;

  /**
   * 使用过滤器，移除此集合中所有符合过滤器要求的元素。
   *
   * @param filter 一个lambda表达式，当表达式返回true时，表示该元素符合过滤器要求
   * @return {boolean} 如果有元素从集合中被删除，则返回true，否则返回false
   * @throws {UnsupportedOperationException} 此方法不受支持
   * @version 1.0
   */
  removeIf(filter: (e: E) => boolean): boolean;

  /**
   * 清空此集合。
   *
   * @throws {UnsupportedOperationException} 此方法不受支持
   * @version 1.0
   */
  clear(): void;

  /**
   * 增加此集合的容量使其可以容纳更多的元素。
   *
   * 给出的容量必须比现有的容量更大，否则将会抛出{@link IllegalArgumentException}。当容量被设定为-1时，表示此集合容量无穷大，之后将不能再增
   * 加容量，也将不再判断容量是否充满。
   *
   * @param capacity 新的容量
   * @throws {IllegalArgumentException} 新的容量比当前容量小或容量已无法增长
   */
  grow(capacity: number): void;
}
